/**
 * Copyright (c) suzuki ryoutoku
 * See this code regarding the Apache License Version 2.0
 * @file StripCreator.h
 * @author suzuki ryoutoku
 */

//=============================================================================
//	Protected include multiple file
//=============================================================================
#ifndef STRIPCREATOR_H
#define STRIPCREATOR_H

//=============================================================================
//	Preprocessor
//=============================================================================
#include "include/declare.h"
#include "Graphics.h"

//=============================================================================
//	Declare class
//=============================================================================
/**
 * @author suzuki ryoutoku
 * @date 2007-10-30
 * @version 1.0
 */
namespace strip
{
  class Triangle;
  class Edge;
}

//=============================================================================
//	define class
//=============================================================================
/**
 * Face's edge
 * @author suzuki ryoutoku
 * @date 2007-10-29
 * @version 1.0
 */
class strip::Edge
{
  // closed member
private:
  int					 m_first;//!< index of first order
  int					m_second;//!< index of second order
  strip::Triangle*	 m_ascending;//!< m_first -> m_second
  strip::Triangle*	m_descending;//!< m_second -> m_first

  // opened method
public:
  Edge();
  ~Edge();

  strip::Triangle* getNeighbourTriangle(strip::Triangle* face);

  // friend class
public:
  friend class strip::Triangle;
  friend class library::graphics::StripCreator;
};


/**
 * Triangle for creating strip
 * @author suzuki ryoutoku
 * @date 2007-10-29
 * @version 1.0
 */
class strip::Triangle
{
public:
  int		  m_face_index;
  int			m_index[3];
  strip::Edge* 	m_edges[3];
  bool		m_edge_path[3];//!< when it's true, ascending order
  int		   	  m_degree;
  int			   m_state;//!< when it's 0, this triangle is not strip yet.

public:
  Triangle(int arg1, int arg2, int arg3);
  ~Triangle();
  strip::Edge* findViaEdgeWithCurrentBufferA(strip::Edge* iedge);
  strip::Edge* findViaEdgeWithCurrentBufferB(strip::Edge* iedge);
  int getThitherVertex(strip::Edge* arg);
  int getAcrossVertex(strip::Triangle* tri);

public:
  friend class StripCreator;
};


/**
 * Creator of strip
 * @author suzuki ryoutoku
 * @date 2007-10-30
 * @version 1.0
 */
class library::graphics::StripCreator
{
public:
  vector<strip::Edge>		m_edges;
  vector<strip::Triangle>	m_triangles;
  library::log::LogManager* m_logger;

public:
  StripCreator(library::log::LogManager* arg);
  ~StripCreator();

  int  createTriangleStrip(int*** stripindex, 
						   int*** relative_triangle,
						   int** stripsum,
						   int* triangle,
						   int* faceindex,
						   int triangle_sum,
						   int vertex_sum);
  
private:
  int createM_edge(int vertex_sum);
  int createM_triangle(int* triangle, int* faceindex,int triangle_sum);
  strip::Triangle* getStartTriangle(void);
  bool extendNormal(vector<strip::Triangle*> &striplist,
					strip::Triangle* start, 
					strip::Edge* edge);

  bool constructTriangleStripData(int* data, 
								  vector<strip::Triangle*> &striplist,
								  strip::Triangle* start,
								  vector<strip::Triangle*> &reverse);
  bool extendReverse(void);

  void displayM_edge(void);
};



//=============================================================================
//	Include gard
//=============================================================================
#endif
